package global

import (
	"fmt"
	"github.com/fsnotify/fsnotify"
	"github.com/jacktea/z-cron/log"
	"github.com/jacktea/z-cron/web"
	"github.com/labstack/echo/v4"
	"github.com/labstack/echo/v4/middleware"
	eLog "github.com/labstack/gommon/log"
	rotateLogs "github.com/lestrrat-go/file-rotatelogs"
	"github.com/spf13/viper"
	"io"
	"os"
	"strings"
	"time"
)

var (
	e = echo.New()
)

func InitConfig(logPath string) *echo.Echo {
	viper.SetConfigName("config")          // name of config file (without extension)
	viper.SetConfigType("yaml")            // REQUIRED if the config file does not have the extension in the name
	viper.AddConfigPath("/etc/tracking/")  // path to look for the config file in
	viper.AddConfigPath("$HOME/.tracking") // call multiple times to add many search paths
	viper.AddConfigPath("./conf/")
	viper.AddConfigPath("../conf/")
	err := viper.ReadInConfig() // Find and read the config file
	if err != nil {
		log.Fatal(err)
	}

	viper.WatchConfig()
	viper.OnConfigChange(reloadConfig)
	// 加载配置
	LoadConfig()

	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	// 设置日志输出
	out, err := getWriter(logPath)
	if err != nil {
		log.Fatal(err)
		fmt.Println(err.Error())
		return nil
	}
	e.Logger.SetOutput(out)
	out = io.MultiWriter(out, os.Stdout)
	log.SetOutput(out)
	//e.Logger.SetOutput(out)
	return e
}

func GetContextPath() string {
	return viper.GetString("application.contextPath")
}

// 启动应用
func Start(logPath string) {
	fmt.Println(logPath)
	e := InitConfig(logPath)
	web.InitRouter(e, GetContextPath())
	log.Fatal(e.Start(fmt.Sprintf(":%d", viper.GetInt64("application.port"))))
}

// 加载配置文件
func LoadConfig() {
	logLevel := viper.GetString("application.logLevel")
	log.SetLevel(logLevel)
	switch strings.ToLower(logLevel) {
	case "error":
		e.Logger.SetLevel(eLog.ERROR)
	case "warn", "warning":
		e.Logger.SetLevel(eLog.WARN)
	case "info":
		e.Logger.SetLevel(eLog.INFO)
	case "debug":
		e.Logger.SetLevel(eLog.DEBUG)
	}
}

// 重新加载配置文件
func reloadConfig(in fsnotify.Event) {
	//fmt.Println("------", in.Name, in.Op, in.String())
	LoadConfig()
}

// 日志输出流
func getWriter(logPath string) (io.Writer, error) {
	return rotateLogs.New(
		logPath+".%Y%m%d%H%M",
		rotateLogs.WithLinkName(logPath), // 生成软链，指向最新日志文件
		// rotatelogs.WithMaxAge(7 * 24 * time.Hour), // 文件最大保存时间
		rotateLogs.WithRotationCount(20), // 最多存20个文件
		rotateLogs.WithRotationTime(24*time.Hour))
}
